
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author debroizr
 */
public class Modification {

    public static void modification(Connection conn) throws SQLException {

        int actionModification;
        boolean exit = false;

        while (!exit) {
            System.out.println("\n*** Choisir une action a effectuer : ***");
            System.out.println("0 : Quitter");
            System.out.println("1 : Modification d'un vol");
            System.out.println("2 : Modification de la reservation d'un client");
            System.out.println("3 : Retour\n");

            actionModification = LectureClavier.lireEntier("votre choix ?\n");
            switch (actionModification) {
                case 0:
                    exit = true;
                    conn.close();
                    System.out.println("\nAu revoir");
                    System.exit(0);
                    break;
                case 1:
                    System.out.println("\nModifier un vol");
                    modifierVol(conn);
                    break;
                case 2:
                    System.out.println("\nModifier la reservation");
                    modifierResa(conn);
                    break;
                case 3:
                    AirChance.menu();
                    exit = true;
                    break;
                default:
                    System.out.println("=> Choix incorrect");
                    AirChance.menu();
            }
        }
    }

    /**
     * modifierVol effectue les opérations nécessaires à la modification
     * d'un vol. 
     * @param conn : Connexion à la base de donnée
     * @throws SQLException : Rollback si la transcation a rencontré une erreur.
     */
    private static void modifierVol(Connection conn) throws SQLException {
        PreparedStatement stmt;
        
        String typeVol;
        int numVol;
        int numAvion;
        String dateVol;

        System.out.println("Quel type de vol voulez-vous modifier ? (Fret/Passager)");
        typeVol = LectureClavier.lireChaine();
        
        if(typeVol.equals("Fret")) {
            numVol = LectureClavier.lireEntier("Veuillez indiquer le numéro du vol à modifier : ");
            
            System.out.println("Date du vol à modifier (format DD-MON-YY) :");
            dateVol = LectureClavier.lireChaine();
            
            //Vérification de la date
            while (!Suppression.isDateValid(dateVol)) {
                System.out.println("Date du vol à modifier (format DD-MON-YY) :\n");
                dateVol = LectureClavier.lireChaine();
            }
            
            numAvion = LectureClavier.lireEntier("Veuillez indiquer le nouvel avion à affecter à ce vol : ");
            
            Scanner sc = new Scanner(System.in);
            
            //Vérification de la validité de l'avion
            /* while(!verifVolumePoids(conn, numAvion, numVol, dateVol)) {
                numAvion = sc.nextInt();
            } */
            
            try {
                
                /* Choix du niveau d'isolation */
                conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
                
                //Modification du vol de fret
                stmt = conn.prepareStatement("Update VolsFret Set NumAvionF = " + numAvion
                        + " Where NumVolF = " + numVol
                        + " And trunc(DateVolF) = to_date(?, 'DD-MON-YY')");

                stmt.setString(1, dateVol);
                ResultSet resultat = stmt.executeQuery();

                //On valide la transaction
                conn.commit();
                
                System.out.println("La modification du vol est prise en compte.");
                
            } catch (SQLException ex) {
                conn.rollback();
                System.out.println("La modification du vol de fret a rencontré une erreur");
                Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        else if(typeVol.equals("Passager")) {
        
        numVol = LectureClavier.lireEntier("Veuillez indiquer le numéro du vol à modifier : ");
            
            System.out.println("Date du vol à modifier (format DD-MON-YY) :\n");
            dateVol = LectureClavier.lireChaine();
            
            //Vérification de la date
            while (!Suppression.isDateValid(dateVol)) {
                System.out.println("Date du vol à modifier (format DD-MON-YY) :\n");
                dateVol = LectureClavier.lireChaine();
            }
            
            /* Choix du niveau d'isolation */
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            
            String choixModifPassagers;
            
            System.out.println("Que voulez-vous modifier ? (Avion/Hotesse/Pilote)");
            choixModifPassagers = LectureClavier.lireChaine();
            
            if(choixModifPassagers.equals("Avion")) {
                numAvion = LectureClavier.lireEntier("Veuillez indiquer le nouvel avion à affecter à ce vol : ");
            
                Scanner sc = new Scanner(System.in);

                //Vérification de la validité de l'avion
                while(!verifNbPlaces(conn, numAvion, numVol, dateVol)) {
                    numAvion = sc.nextInt();
                }

                try {
                    //Modification de l'avion passager
                    stmt = conn.prepareStatement("Update VolsPassagers Set NumAvionP = " + numAvion
                            + " Where NumVolP = " + numVol
                            + " And trunc(DateVolP) = to_date(?, 'DD-MON-YY')");

                    stmt.setString(1, dateVol);
                    stmt.executeQuery();

                    //On valide la transaction
                    conn.commit();
                
                } catch (SQLException ex) {
                    conn.rollback();
                    System.out.println("La modification du vol de passagers a rencontré une erreur");
                    Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
            else if(choixModifPassagers.equals("Hotesse")) {
                int numHotesseAncien = LectureClavier.lireEntier("Veuillez indiquer le numéro de l'hotesse à remplacer dans ce vol : ");
                int numHotesseNouveau = LectureClavier.lireEntier("Veuillez indiquer le numéro de l'hotesse à ajouter à ce vol : ");
                
                Scanner sc = new Scanner(System.in);
                
                try {
                    //Modification de l'avion passager
                    stmt = conn.prepareStatement("Update AffectationH Set NumPersoH = " + numHotesseNouveau
                            + " Where NumVol = " + numVol
                            + " And trunc(DateVol) = to_date(?, 'DD-MON-YY')"
                            + " And NumPersoH = " + numHotesseAncien);

                    stmt.setString(1, dateVol);
                    stmt.executeQuery();

                    //On valide la transaction
                    conn.commit();
                
                } catch (SQLException ex) {
                    conn.rollback();
                    System.out.println("La modification du vol de passagers a rencontré une erreur");
                    Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
            else if(choixModifPassagers.equals("Pilote")) {
                int numPiloteAncien = LectureClavier.lireEntier("Veuillez indiquer le numéro du pilote à remplacer dans ce vol : ");
                int numPiloteNouveau = LectureClavier.lireEntier("Veuillez indiquer le numéro du pilote à ajouter à ce vol : ");
                
                Scanner sc = new Scanner(System.in);
                
                try {
                    //Modification de l'avion passager
                    stmt = conn.prepareStatement("Update AffectationP Set NumPersoP = " + numPiloteNouveau
                            + " Where NumVol = " + numVol
                            + " And trunc(DateVol) = to_date(?, 'DD-MON-YY')"
                            + " And NumPersoP = " + numPiloteAncien);

                    stmt.setString(1, dateVol);
                    stmt.executeQuery();

                    //On valide la transaction
                    conn.commit();
                
                } catch (SQLException ex) {
                    conn.rollback();
                    System.out.println("La modification du vol de passagers a rencontré une erreur");
                    Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    
    /**
     * modifierResa effectue les opérations nécessaires à la modification
     * d'un vol. 
     * @param conn : Connexion à la base de donnée
     * @throws SQLException : Rollback si la transcation a rencontré une erreur.
     */
    private static void modifierResa(Connection conn) throws SQLException {
        PreparedStatement stmt;
        
        // conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
        
        String typeVol;
        int numVol;
        int numAvion;
        int numResa;
        String dateVol;

        System.out.println("Quel type de réservation voulez-vous modifier ? (Fret/Passager)");
        typeVol = LectureClavier.lireChaine();
        
        if(typeVol.equals("Fret")) {
            numResa = LectureClavier.lireEntier("Veuillez indiquer votre numéro de réservation : ");
            
            numVol = LectureClavier.lireEntier("Veuillez indiquer le numéro du vol : ");
            
            System.out.println("Date du vol (format DD-MON-YY) :\n");
            dateVol = LectureClavier.lireChaine();
            
            //Vérification de la date
            while (!Suppression.isDateValid(dateVol)) {
                System.out.println("Date du vol (format DD-MON-YY) :\n");
                dateVol = LectureClavier.lireChaine();
            }
            
            float NouveauVolume = LectureClavier.lireFloat("Quel est votre nouveau volume ?");
            float NouveauPoids = LectureClavier.lireFloat("Quel est votre nouveau poids ?");
            
            Scanner sc = new Scanner(System.in);
            
            //Vérification du poids et du volume par rapport à l'avion
            /* while(!verifVolumePoidsResa(conn, numVol, dateVol, NouveauVolume, NouveauPoids)) {
                numAvion = sc.nextInt();
            } */
            
            try {
                //Modification de la réservation
                stmt = conn.prepareStatement("Update ResaFret Set Volume = " + NouveauVolume
                        + ", Poids = " + NouveauPoids
                        + " Where NumVol = " + numVol
                        + " And trunc(DateVol) = to_date(?, 'DD-MON-YY')");

                stmt.setString(1, dateVol);
                stmt.executeQuery();

                //On valide la transaction
                conn.commit();
                
            } catch (SQLException ex) {
                conn.rollback();
                System.out.println("La modification du vol de fret a rencontré une erreur");
                Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        else if(typeVol.equals("Passager")) {
        
            numResa = LectureClavier.lireEntier("Veuillez indiquer votre numéro de réservation : ");
            
            numVol = LectureClavier.lireEntier("Veuillez indiquer le numéro du vol : ");
            
            System.out.println("Date du vol (format DD-MON-YY) :\n");
            dateVol = LectureClavier.lireChaine();
            
            //Vérification de la date
            while (!Suppression.isDateValid(dateVol)) {
                System.out.println("Date du vol (format DD-MON-YY) :\n");
                dateVol = LectureClavier.lireChaine();
            }
            
            System.out.println("Que voulez-vous modifier ? (Place)");
            String choixModifResa = LectureClavier.lireChaine();
            
            if(choixModifResa.equals("Place")) {
                Scanner sc = new Scanner(System.in);
                int numPlace;

                //Sélection des places libres pour cette réservation dans ce vol. 
                stmt = conn.prepareStatement("Select NumPlace From ResaPassager"
                        + " Where NumPlace Not In (Select NumPlace From Passager"
                        + " Where NumVolP = " + numVol
                        + " And trunc(DateVolP) = to_date(?, 'DD-MON-YY')");

                stmt.setString(1, dateVol);
                ResultSet resutlat = stmt.executeQuery();
                
                while(resutlat.next()) {
                    numPlace = resutlat.getInt("NumPlace");
                    System.out.println("Numéro d'une place libre : " + numPlace);
                }
                
                numPlace = LectureClavier.lireEntier("Quelle est votre nouvelle place ?");
                
                try {
                    //Modification de la place
                    stmt = conn.prepareStatement("Update ResaPassager Set NumPlace = " + numPlace
                            + " Where NumVolP = " + numVol
                            + " And trunc(DateVolP) = to_date(?, 'DD-MON-YY')");

                    stmt.setString(1, dateVol);
                    stmt.executeQuery();

                    //On valide la transaction
                    conn.commit();
                
                } catch (SQLException ex) {
                    conn.rollback();
                    System.out.println("La modification du vol de passagers a rencontré une erreur");
                    Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    
    public static boolean verifVolumePoids(Connection conn, int numAvion, int numVol, String dateVol) throws SQLException {
        Boolean volumePoidsOK = false;
        PreparedStatement stmt;
        float volumeMaxAncien;
        float poidsMaxAncien;
        float volumeMaxNouveau;
        float poidsMaxNouveau;
        
        try {
            stmt = conn.prepareStatement("Select VolumeMax, PoidsMax From AvionsFret"
                    + " Where NumAvionF = " + numAvion);
            ResultSet resultat = stmt.executeQuery();
            resultat.next();
            volumeMaxNouveau = resultat.getInt("VolumeMax");
            poidsMaxNouveau = resultat.getInt("PoidsMax");
            
            stmt = conn.prepareStatement("Select Distinct VolumeMax, PoidsMax From AvionsFret"
                    + " Natural Join VolsFret"
                    + " Where NumVolF = " + numVol
                    + " And trunc(DateVolF) = to_date(?, 'DD-MON-YY')");
            
            stmt.setString(1, dateVol);
            resultat = stmt.executeQuery();
                
            resultat.next();
            volumeMaxAncien = resultat.getInt("VolumeMax");
            poidsMaxAncien = resultat.getInt("PoidsMax");
            
            if(volumeMaxNouveau >= volumeMaxAncien) {
                volumePoidsOK = true;
            }
            
            if(poidsMaxNouveau >= poidsMaxAncien) {
                volumePoidsOK = true;
            }
            
            if(poidsMaxNouveau <= poidsMaxAncien || volumeMaxNouveau <= volumeMaxAncien) {
                volumePoidsOK = false;
                System.out.println("Le poids ou le volume dépasse les capacités de l'avion. Veuillez recommencer.");                 
            }
            
        } catch (SQLException ex) {
            conn.rollback();
            System.out.println("La vérification du poids et du volume a rencontré une erreur.");
            Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return volumePoidsOK;
    }
    
    public static boolean verifVolumePoidsResa(Connection conn, int numVol, String dateVol, float NouveauVolume, float NouveauPoids) throws SQLException {
        Boolean volumePoidsOK = false;
        PreparedStatement stmt;
        float volumeMaxAncien;
        float poidsMaxAncien;
        
        try {
            stmt = conn.prepareStatement("Select Distinct VolumeMax, PoidsMax From AvionsFret"
                    + " Natural Join VolsFret"
                    + " Where NumVolF = " + numVol
                    + " And trunc(DateVolF) = to_date(?, 'DD-MON-YY')");
            
            stmt.setString(1, dateVol);
            ResultSet resultat = stmt.executeQuery();
                
            resultat.next();
            volumeMaxAncien = resultat.getFloat("VolumeMax");
            poidsMaxAncien = resultat.getFloat("PoidsMax");
            
            if(NouveauVolume > volumeMaxAncien) {
                volumePoidsOK = true;
            }
            
            if(NouveauPoids > poidsMaxAncien) {
                volumePoidsOK = true;
            }
            
            if(NouveauPoids < poidsMaxAncien || NouveauVolume < volumeMaxAncien) {
                volumePoidsOK = false;
                System.out.println("Le poids ou le volume dépasse les capacités de l'avion. Veuillez recommencer.");                 
            }
            
        } catch (SQLException ex) {
            conn.rollback();
            System.out.println("La vérification du poids et du volume a rencontré une erreur.");
            Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return volumePoidsOK;
    }
    
    public static boolean verifNbPlaces(Connection conn, int numAvion, int numVol, String dateVol) throws SQLException {
        Boolean nbPlacesOK = false;
        PreparedStatement stmt;
        int Nb1Cl;
        int Nb2Cl;
        int nbPlacesNouveau;
        int nbPlacesAncien;
        
        try {
            stmt = conn.prepareStatement("Select Nb1Cl, Nb2Cl From AvionsPassagers"
                    + " Where NumAvionP = " + numAvion);
            ResultSet resultat = stmt.executeQuery();
            resultat.next();
            Nb1Cl = resultat.getInt("Nb1Cl");
            Nb2Cl = resultat.getInt("Nb2Cl");
            
            nbPlacesNouveau = Nb1Cl + Nb2Cl;
            
            stmt = conn.prepareStatement("Select count(NumPlace) as nbPlacesAncien From VolsPassagers"
                    + " Natural Join AvionsPassagers"
                    + " Where NumVolP = " + numVol
                    + " And trunc(DateVolP) = to_date(?, 'DD-MON-YY')");
            
            stmt.setString(1, dateVol);
            resultat = stmt.executeQuery();
            resultat.next();
            
            nbPlacesAncien = Integer.parseInt(resultat.getString("nbPlacesAncien"));
            
            if(nbPlacesAncien == nbPlacesNouveau) {
                nbPlacesOK = true;
            }
            
        } catch (SQLException ex) {
            conn.rollback();
            System.out.println("La vérification du poids et du volume a rencontré une erreur.");
            Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return nbPlacesOK;
    }
}
